package com.lyl.mallcloud.controller;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lyl.mallcloud.mapper.OrdersMapper;
import com.lyl.mallcloud.mapper.ProductsMapper;
import com.lyl.mallcloud.mapper.UsersMapper;
import com.lyl.mallcloud.pojo.*;
import com.lyl.mallcloud.pojo.page.PageParams;
import com.lyl.mallcloud.service.IProductsService;
import com.lyl.mallcloud.utils.AliOssUtil;
import com.lyl.mallcloud.utils.ExcelUtils;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author liyunlong
 * @since 2024-05-11
 */
@RestController
@Slf4j
public class ProductsController {

    @Autowired
    ProductsMapper productsMapper;
    @Autowired
    IProductsService productsService;
    @Autowired
    UsersMapper usersMapper;
    @Autowired
    private AliOssUtil aliOssUtil;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    OrdersMapper ordersMapper;


    /***
     * @Description: 商品的分页查询 这里设置的是每页展示4条数据
     * @Author: Liyunlong
     * @Date: 2024/5/13
     */
    @GetMapping("/productList")
    public Result productList(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "3") Integer pageSize) {
        List<Products> list;
        ProductPage productPage = null;
        try {
            // 设置分页参数
            PageParams pageParams = new PageParams();
            pageParams.setPageNum(pageNum);
            pageParams.setPageSize(pageSize);
            PageHelper.startPage(pageParams.getPageNum(), pageSize);
            List<Products> products = productsMapper.selectList(null);
            PageInfo<Products> pageInfo = new PageInfo<>(products);
            int pages = pageInfo.getPages();
            int pageNum1 = pageInfo.getPageNum();
            list = pageInfo.getList();
            productPage = new ProductPage();
            productPage.setProductsList(list);
            productPage.setPageNum(pageNum1);
            productPage.setPages(pages);
        } catch (Exception ignored) {
        }
        return Result.success(productPage);
    }

    /***
     * @Description: 更新商品的状态，上下架
     * @Author: Liyunlong
     * @Date: 2024/5/13
     */
    @PostMapping("/updateProductStatus/{id}")
    public Result updateProductStatus(@PathVariable(value = "id") Long id) {
        Products products = productsMapper.selectById(id);
        Boolean status = products.getStatus();
        if (status) {
            products.setStatus(false);
            productsMapper.updateById(products);
            log.info("商品：{}，下架了", products.getProductName());
        }
        if (!status) {
            products.setStatus(true);
            productsMapper.updateById(products);
            log.info("商品：{}，上架了", products.getProductName());
        }
        return Result.success();
    }

    /***
     * @Description: 查看商品的详细信息
     * @Author: Liyunlong
     * @Date: 2024/5/13
     */
    @GetMapping("/productInfo")
    public Result getProductInfo(@RequestParam(value = "id") Long id) {
        Products product = productsMapper.selectById(id);
        return Result.success(product);
    }

    /***
     * @Description: 数据看板 商品数据 热卖商品
     * @Author: Liyunlong
     * @Date: 2024/5/13
     */
    @GetMapping("/hotProduct")
    public Result hotProduct() {
        List<Map<String, Object>> salesProductItemList;
        try {
            QueryWrapper<Orders> salesQueryWrapper = new QueryWrapper<>();
            salesQueryWrapper.ge("quantity", 100);
            salesQueryWrapper.orderByDesc("quantity");
            List<Orders> salesOrderList = ordersMapper.selectList(salesQueryWrapper);
            Map<Integer, Long> productQuantityMap = salesOrderList.stream().collect(Collectors.groupingBy(Orders::getProductId, Collectors.summingLong(Orders::getQuantity)));
            // 包含商品ID和总数量的列表
            List<Map.Entry<Integer, Long>> sortedEntries = new ArrayList<>(productQuantityMap.entrySet());
            // 按照总数量进行降序排序
            sortedEntries.sort(Map.Entry.<Integer, Long>comparingByValue().reversed());
            // 分别提取ID和数量，创建新的列表
            List<Integer> productIds = sortedEntries.stream().map(Map.Entry::getKey).toList();
            // 将所有商品的总数量放入一个集合
            List<Long> totalQuantities = sortedEntries.stream().map(Map.Entry::getValue).toList();
            // List<Products> salesProductList = productsMapper.selectBatchIds(productIds);
            List<Products> salesProductList = new ArrayList<>(productIds.size());
            for (Integer id : productIds) {
                Products product = productsMapper.selectById(id);
                if (product != null) {
                    salesProductList.add(product);
                }
            }
            AtomicInteger salesRank = new AtomicInteger(1);
            salesProductItemList = IntStream.range(0, productIds.size()).boxed().map(i -> {
                Products product = salesProductList.get(i);
                // Integer productId = productIds.get(i);
                Long totalQuantity = totalQuantities.get(i);
                return createProductItemWithQuantity(product, salesRank.getAndIncrement(), /*productId,*/ totalQuantity);
            }).toList();

        } catch (Exception e) {
            // 处理异常
            throw new RuntimeException("查询商品数据失败", e);
        }
        return Result.success(salesProductItemList);
    }
    // 短缺商品

    @GetMapping("/shortProduct")
    public Result shortProduct() {
        // 查询按照库存排序的商品
        // 待补货 商品 限制是 库存量在 10-200  之间的商品
        QueryWrapper<Products> stockQueryWrapper = new QueryWrapper<>();
        stockQueryWrapper.ge("stock", 10);
        stockQueryWrapper.le("stock", 200);
        stockQueryWrapper.orderByAsc("stock");
        List<Products> stockProductList = productsMapper.selectList(stockQueryWrapper);
        AtomicInteger stockRank = new AtomicInteger(1);
        List<Map<String, Object>> stockProductItemList = stockProductList.stream().map(product -> createProductItem(product, stockRank.getAndIncrement())).toList();
        return Result.success(stockProductItemList);
    }

    private Map<String, Object> createProductItemWithQuantity(Products product, int rank, Long totalQuantity) {
        Map<String, Object> productItemInfo = new HashMap<>();
        productItemInfo.put("id", product.getId());
        productItemInfo.put("rank", rank);
        productItemInfo.put("productName", product.getProductName());
        productItemInfo.put("price", product.getPrice());
        productItemInfo.put("stock", product.getStock());
        productItemInfo.put("views", product.getViews());
        productItemInfo.put("launchDate", product.getLaunchDate());
        productItemInfo.put("salesVolume", product.getSalesVolume());
        productItemInfo.put("totalQuantity", totalQuantity);
        return productItemInfo;
    }

    private Map<String, Object> createProductItem(Products product, int rank) {
        Map<String, Object> productItemInfo = new HashMap<>();
        productItemInfo.put("id", product.getId());
        productItemInfo.put("rank", rank);
        productItemInfo.put("productName", product.getProductName());
        productItemInfo.put("price", product.getPrice());
        productItemInfo.put("stock", product.getStock());
        productItemInfo.put("views", product.getViews());
        productItemInfo.put("launchDate", product.getLaunchDate());
        productItemInfo.put("salesVolume", product.getSalesVolume());
        return productItemInfo;
    }

    /***
     * @Description: 添加商品信息
     * @Author: Liyunlong
     * @Date: 2024/5/13
     */
    @PostMapping("/addProduct")
    public Result addProduct(@RequestBody ProductDTO productDTO) {
        Products products = new Products();
        if(productDTO.getProductName()==null){
            return Result.error("商品名不能为空");
        }
        BeanUtils.copyProperties(productDTO, products);
        products.setStatus(true);
        products.setViews(0);
        products.setLaunchDate(LocalDate.now());
        products.setIsDeleted(false);
        products.setSalesVolume(0);
        boolean added = productsService.save(products);
        if (added) {
            log.info("商品添加成功");
            return Result.success();
        } else {
            log.error("商品添加失败");
            return Result.error("商品添加失败");
        }
    }

    /***
     * @Description: 删除商品
     * @Author: Liyunlong
     * @Date: 2024/5/13
     */
    @DeleteMapping("/deleteProduct")
    public Result delete(@RequestParam(value = "id") Long id) {
        productsMapper.deleteById(id);
        log.info("删除用户信息：{}", id);
        return Result.success();
    }

    /***
     * @Description: 批量删除商品信息
     * @Author: Liyunlong
     * @Date: 2024/5/13
     */
    @DeleteMapping("/deleteBatch/{ids}")
    public Result deleteBatch(@PathVariable("ids") List<String> ids) {
        productsMapper.deleteBatchIds(ids);
        return Result.success();
    }


    /***
     * @Description: 更新商品
     * @Author: Liyunlong
     * @Date: 2024/5/13
     */
    @PostMapping("/updateProduct")
    public Result updateProduct(@RequestBody ProductDTO productDTO) {
        Products products = new Products();
        BeanUtils.copyProperties(productDTO, products);
        boolean save = productsService.saveOrUpdate(products);
        if (save) {
            log.info("商品信息修改成功");
            return Result.success();
        } else {
            log.error("商品修改失败");
            return Result.error("修改失败");
        }
    }

    @PostMapping("/upload")
    public Result upload(@RequestParam("file") MultipartFile file) throws IOException {
        if (!file.isEmpty()) {
            // 原始文件名
            String originalFilename = file.getOriginalFilename();
            // 截取文件名后缀  xxx.png
            assert originalFilename != null;
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            // 构造新文件名称
            String objectName = UUID.randomUUID() + extension;
            // 返回文件请求路径
            String filePath = aliOssUtil.upload(file.getBytes(), objectName);
            return Result.success(filePath);
        }
        return Result.error("图片上传失败");
    }

    /***
     * @Description: 商品信息的的导出
     * @Author: Liyunlong
     * @Date: 2024/5/13
     */
    @GetMapping("/export")
    public void export(HttpServletResponse response) throws IOException {
        String excelName = "商品信息";
        List<Products> list = productsMapper.selectList(null);
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String fileName = excelName + now.format(formatter);
        log.info("导出商品信息文件：{}", fileName);
        ExcelUtils.exportExcel(new ArrayList<>(list), excelName, excelName, Products.class, fileName, response);
    }

    /***
     * @Description: 商品加入秒杀
     * @Author: Liyunlong
     * @Date: 2024/5/13
     */
    @PostMapping("/secKill/{id}")
    public Result seckill(@PathVariable(value = "id") Long id) {
        Products products = productsMapper.selectById(id);
        String seckillproduct = JSONUtil.toJsonStr(products);
        int randomMinutes = new Random().nextInt(30) + 1;
        long totalExpiration = 1L + TimeUnit.DAYS.toSeconds(1) + TimeUnit.MINUTES.toSeconds(randomMinutes);
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("seckill:product:" + id, seckillproduct, totalExpiration, TimeUnit.SECONDS);
        if (aBoolean) {
            log.info("商品加入秒杀成功");
            return Result.success();
        } else {
            log.info("商品加入秒杀失败");
            return Result.error("商品已被添加过秒杀，请勿重复添加");
        }
    }
}

